

#include "mrpcchannel.h"
#include <netinet/in.h>
#include "muduo/net/EventLoop.h"
#include "muduo/net/InetAddress.h"
#include "muduo/net/TcpClient.h"
#include "muduo/base/Timestamp.h"

/**
 * 1. 组装request
 * 2. 发起调用（使用tcp或者muduo）
 *
 *  buff规则：format(int: 0=protobuff, 1=json) args(4个字节) header_str12 args_str   (这里的12代指args_size)
 *         例如： 04UserServicelogin5 zs123
 *
 */
void MRpcChanner::CallMethod(const google::protobuf::MethodDescriptor *method,
                             google::protobuf::RpcController *controller,
                             const google::protobuf::Message *request,
                             google::protobuf::Message *response, google::protobuf::Closure *done)
{
    // protobuff
    // 消息
    int argSize;
    std::string argStr, headerStr;

    if (request->SerializeToString(&argStr))
    {
        argSize = argStr.size();
    }

    // 创建并设置RpcHeader
    rpc::RpcHeader header;
    header.set_servicename(method->service()->name());
    header.set_methodname(method->name());
    header.set_argrsize(argSize);

    // 序列化header
    header.SerializeToString(&headerStr);

    // 获取header大小并转换为网络字节序
    uint32_t netHeaderSize = htonl(headerStr.size());

    // 构建完整消息
    std::string allString;
    allString.append("0"); // 0表示protobuff
    allString.append(reinterpret_cast<const char *>(&netHeaderSize), 4);
    allString += headerStr;
    allString += argStr;

    std::cout << "headerStr = " << headerStr << std::endl;
    std::cout << "netHeaderSize = " << netHeaderSize << std::endl;
    std::cout << "argStr = " << argStr << std::endl;
    std::cout << "allString = " << allString << std::endl;

    // 开始send
    std::string res = send(allString);
    if (!response->ParseFromString(res))
    {
        std::cout << "response parse failed. res" << res << std::endl;
    }
}

/**
 * buff规则（json）：format+args(4个字节)+{"serviceName":"","methodName":"", "argSize":""}+args_str(json)
 */
void MRpcChanner::CallMethodJson(const std::string &serviceName,
                                 const std::string &methodName,
                                 RpcJsonParam jsonParam)
{
    // 消息
    int argSize;
    std::string argStr, headerStr, allString;

    std::cout << "json json = " << jsonParam.requestJson << std::endl;

    argStr = jsonParam.requestJson.dump();
    // jsonParam.requestJson 转为string

    argSize = argStr.size();

    headerStr = jsonFormatFromKV("serviceName", serviceName, "methodName", methodName, "argrSize", std::to_string(argSize));
    uint32_t netHeaderSize = htonl(headerStr.size());
    //
    allString.append("1"); // json
    allString.append(reinterpret_cast<const char *>(&netHeaderSize), 4);
    allString += headerStr;
    allString += argStr;

    std::cout << "headerStr = " << headerStr << std::endl;
    std::cout << "netHeaderSize = " << netHeaderSize << std::endl;
    std::cout << "argStr = " << argStr << std::endl;
    std::cout << "allString = " << allString << std::endl;

    // 开始send
    std::string res = send(allString);
    // res = {"success":true, "message":"login success"};
    json resJson = json::parse(res);
    jsonParam.response.success = resJson["success"];
    if (resJson.contains("message") && resJson["message"].is_string())
    {
        jsonParam.response.message = resJson["message"].get<std::string>();
    }
    else
    {
        // 处理异常：如果不是字符串，尝试转换为字符串或赋默认值
        jsonParam.response.message = resJson["message"].dump(); // 转为JSON字符串
        // 或者使用固定默认值：jsonParam.response.message = "未知消息";
    }

    // 解析dataJson字段（处理可能的null）
    if (resJson.contains("dataJson"))
    { // 先判断字段是否存在
        if (!resJson["dataJson"].is_null())
        {
            jsonParam.response.dataJson = resJson["dataJson"];
        }
        else
        {
            jsonParam.response.dataJson = json::object(); // 空对象默认值
        }
    }
    else
    {
        jsonParam.response.dataJson = json::object(); // 字段不存在时的默认值
    }
}

std::string MRpcChanner::send(const std::string &message)
{
    MrpcApplication::Conf conf = MrpcApplication::_conf;
    std::string rpcserverip = conf.at("rpcserverip");
    std::string rpcserverport = conf.at("rpcserverport");

    muduo::net::EventLoop loop;
    muduo::net::InetAddress serverAddr(rpcserverip, static_cast<uint16_t>(atoi(rpcserverport.c_str())));
    muduo::net::TcpClient client(&loop, serverAddr, "SingleClient");

    std::string response;
    // 标记消息是否已发送
    bool messageSent = false;
    // 消息回调：收到服务器回复后关闭连接
    client.setMessageCallback([&loop, &response](const muduo::net::TcpConnectionPtr &conn,
                                                 muduo::net::Buffer *buf,
                                                 muduo::Timestamp time)
                              {
        response = buf->retrieveAllAsString();
        std::cout << "Received from server: " << response << std::endl;
        
        // 收到回复后关闭连接并退出事件循环
        conn->shutdown();
        loop.quit(); });
    // 连接回调：连接建立后发送消息
    client.setConnectionCallback([&](const muduo::net::TcpConnectionPtr &conn)
                                 {
        if (conn->connected() && !messageSent) {
            std::cout << "Connected to server, sending message..." << std::endl;
            // 发送入参中的消息
            conn->send(message);
            messageSent = true;
        } else if (!conn->connected()) {
            std::cout << "Disconnected from server" << std::endl;
        } });

    client.connect();
    loop.loop(); // 运行事件循环，直到收到回复后退出
    std::cout << "Response: " << response << std::endl;
    return response;
}
